Like any kind of apps, JavaScript apps also have to be written well.
Otherwise, we run into all kinds of issues later on.
In this article, we’ll look at ways to improve our JavaScript code.
Calling hasOwnProperty Safely
The hasOwnProperty
is part of Object.prototype
, which means that it can be overridden or removed.
So to make sure that it’s always available, we can call it directly from the Object.prototype
.
We can write:
const hasOwnProperty = Object.prototype.hasOwnProperty;
or:
const hasOwnProperty = {}.hasOwnProperty;
Then we can call it by writing:
hasOwnProperty.call(dict, 'james');
given that we have:
const dict = {
james: 33,
bob: 22,
mary: 41
};
We can abstract the logic for checking entries our of the object.
For instance, we can create a class with the items.
We can write:
class Dict {
constructor(elements) {
this.elements = elements;
}
has(key) {
return {}.hasOwnProperty.call(this.elements, key);
}
set(key, val) {
this.elements[key] = val;
}
get(key) {
return this.elements[key];
}
remove(key) {
delete this.elements[key];
}
}
We created a Dict
class to hold an elements
instance variable that we can manipulate with methods for doing common dictionary operations.
has
checks if the property exists.
set
sets the key with the value.
get
gets the value with the given key.
remove
removes an entry from the object.
Now we can use it by writing:
const dict = new Dict({
james: 33,
bob: 22,
mary: 41
});
Use Arrays for Ordered Collections
Arrays should be used for ordered collections.
Ordered collections have an index and they are iterated through with the given order.
We can create an array by writing:
const arr = [1, 2, 3];
Then we can use it by writing:
for (const a of arr) {
console.log(a);
}
We looped through the arr
array with the for-of loop.
It always iterates from the start to the end, so the order is predictable.
The for-of loop shouldn’t be mistaken for the for-in loop which loops through items in an unpredictable order.
Never Add Enumerable Properties to Object.prototype
We shouldn’t add enumerable properties to Object.prototype
.
Object.prototype
is a property that we don’t own so we shouldn’t change it since it’ll give results that most people don’t expect.
Also, the for-in loop will pick up the enumerable property of a prototype so it’ll be iterated through by it.
We don’t want that to happen.
If we want to add a property to Object.prototype
, then it should be made non-enumerable.
For instance, we can write:
Object.defineProperty(Object.prototype, "allKeys", {
value() {
const result = [];
for (const key in this) {
result.push(key);
}
return result;
},
writable: true,
enumerable: false,
configurable: true
});
We set enumerable
to false
so that it won’t be picked up by the for-in loop.
Conclusion
We shouldn’t add enumerable properties to Object.prototype
.
Also, to call hasOwnProperty
safely, we shouldn’t call it directly from the object itself since it can be modified.
Arrays are good for ordered collections.